package br.com.klis.easycontrast;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Vibrator;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.TextView;
import br.com.klis.easycontrast.model.Constants;
import br.com.klis.easycontrast.model.ContrastMode;
import br.com.klis.easycontrast.model.ContrastSession;
import br.com.klis.easycontrast.presenter.ContrastSessionPresenter;
import br.com.klis.easycontrast.view.ContrastSessionViewInterface;

/**
 * Interface para execucao do tempo(quente e frio) e controle da sessao de contraste
 * @author Inacio
 *
 */
public class ContrastActivity extends Activity implements ContrastSessionViewInterface{
	private int minutes;
	private int seconds;
	
	private AppCountDownTimer counter;
	private Ringtone alarmRingtone;
	private Presenter listener;
	
	private ImageButton playButton, pauseButton, restartButton;
	private TextView timeTextView, contrastModeTextView, repetitionTextView;
	private ProgressBar progressBar;
	private ProgressBar progressBar1;
	
	private static final int DIALOG_SESSION_FINISH = 3;
	private static final int DIALOG_CONFIRM_EXIT_APP = 2;
	
	private static final int MENU_RESTART_SESSION = 0;
	private static final int MENU_CONFIG = 1;
	private static final int MENU_ABOUT = 2;
	
	private Mode actualMode = Mode.init;
	
	private enum Mode{
		init, running, pause;
	}
	
	/**
	 * @see android.app.Activity#onCreate(Bundle)
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState); 
        setContentView(R.layout.contrast); 
     
        Log.d("EasyContrast", "entrou no on create....");
        
        InitializeUI(true); 
	}
	
	/**
	 * Obtem os elementos da tela para 
	 */
	private void bindViewComponents(){
		playButton = (ImageButton) findViewById(R.id.playButton);
		pauseButton = (ImageButton) findViewById(R.id.pauseButton);
		restartButton = (ImageButton) findViewById(R.id.restartButton);
		timeTextView = (TextView)findViewById(R.id.timeTextView);
		repetitionTextView = (TextView)findViewById(R.id.repetitionTextView);
		contrastModeTextView = (TextView)findViewById(R.id.contrastModeTextView);
		playButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
		    	listener.play();
			}
		});
    	
    	pauseButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				listener.pause();
			}
		});
    	
    	restartButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				listener.restart();
			}
		});
    	progressBar = (ProgressBar)findViewById(R.id.progressBarTop);
    	progressBar1 = (ProgressBar)findViewById(R.id.progressBarBottom);
	}
	
	/**
     * Configura os objetos (views) do formulario
     */
    private void configureViews(){
    	//timeTextView.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/ballsontherampage.ttf"));
    }
    
    @Override
    public void setPauseMode(){
    	enablePlayControl(true);
		enablePauseControl(false);
		enableRestartControl(true);
		this.actualMode = Mode.pause;
    }
    
    @Override
    public void setRunningMode(){
    	enablePlayControl(false);
		enablePauseControl(true);
		enableRestartControl(true);
		this.actualMode = Mode.running;
    }
    
    @Override
    public void setInitMode(){
    	enablePlayControl(true);
		enablePauseControl(false);
		enableRestartControl(false);
		this.actualMode = Mode.init;
    }
    
    @Override
    public void initProgressBar(int maxValueMin, int maxValueSec){
    	progressBar.setMax(maxValueMin*60+maxValueSec);
    	progressBar1.setMax(maxValueMin*60+maxValueSec);
    	resetProgressBar();
    }
    
    private void resetProgressBar(){
    	progressBar.setProgress(0);
    	progressBar1.setProgress(0);
    }
	
    /**
     * Trata a habilitacao do botao passado como parametro
     * @param button
     * @param enabled
     */
	private void enableButton(ImageButton button, boolean enabled) {
    	int alpha = 255;
    	if ( !enabled )
    		alpha = 128;
    	
    	button.setAlpha(alpha);
    	button.setEnabled(enabled);
    }
    
	/**
	 * Atualiza o texto do cronometro
	 */
    @Override
    public void updateTextView(int minutes, int seconds) {
    	this.minutes = minutes;
    	this.seconds = seconds;
    	String min = null;
    	String sec = null;
    	
    	min = Integer.toString(minutes);
    	if ( minutes < 10 ) {
    		min = "0"+min;
    	}
    	
    	sec = Integer.toString(seconds);
    	if ( seconds < 10 ) {
    		sec = "0"+sec;
    	}
    	progressBar.setProgress(progressBar.getMax()-(minutes*60+seconds));
    	progressBar1.setProgress(progressBar1.getMax()-(minutes*60+seconds));
    	
    	String textTime = min + ":"+sec;
    	((TextView)findViewById(R.id.timeTextView)).setText(textTime);
    	
    	notificacao(textTime);
    }
    
    /**
     * Toca o alarme
     */
    private void playAlarm() {
    	Uri uri =  RingtoneManager.getActualDefaultRingtoneUri(this.getApplicationContext(), RingtoneManager.TYPE_ALARM);
    	alarmRingtone = RingtoneManager.getRingtone(this.getApplicationContext(), uri);
    	alarmRingtone.play();
    }

    /**
     * Trata a finalizacao de um tempo
     */
    @Override
	public void finishTime(){
    	if ( listener.playSound())
    		playAlarm();
    	
    	if ( listener.vibrate() )
    		((Vibrator)this.getSystemService(VIBRATOR_SERVICE)).vibrate(new long[] {500, 500, 500, 500, 500, 500}, -1);
    	
    	if(listener.isLastTimeOfSession()){
    		showDialog(DIALOG_SESSION_FINISH);
    	}else{
    		openFinishTimeScreen();
    	}
	}
    
    /**
     * Abre a Tela de Final de Tempo
     */
    private void openFinishTimeScreen(){
    	 AlertDialog.Builder builder = new AlertDialog.Builder(this);
    	 Resources res = getResources();
    	 StringBuilder sb = new StringBuilder(res.getString(R.string.finish_time_message_1)).append(" ");
    	 sb.append(res.getString(Integer.valueOf(listener.getContrastModeAtualText()))).append(" ");
    	 sb.append(res.getString(R.string.finish_time_message_2)).append(" ");
    	 sb.append(listener.getRepetitionCount()).append(" ");
    	 sb.append(res.getString(R.string.finish_time_message_3));
    		builder.setMessage(sb.toString());
    		builder.setTitle(R.string.dialog_finish_title);
    		builder.setIcon(android.R.drawable.ic_menu_info_details);
    		builder.setNeutralButton("OK", new DialogInterface.OnClickListener() {
    			public void onClick(DialogInterface dialog, int which) {
    				if ( listener.playSound() )
    					alarmRingtone.stop();
    				if ( listener.vibrate())
    					((Vibrator)getSystemService(VIBRATOR_SERVICE)).cancel();
    				
    				listener.createTime();
    				if(listener.isNewRepetition()){
    					listener.updateRepetitionText();
    				}
    				listener.updateTimeScreen(true);
    				listener.initProgressBar();
    			}
    		});
    		builder.show();
    }
    
    /**
     * Seta o presenter para tratar os eventos da visao
     * Objetivo desacoplar metodos que sao independentes das classes de visao
     */
	@Override
	public void setPresenter(Presenter listener) {
		this.listener = listener;
	}

	/**
	 * Trata a habilitacao do botao play de tempo
	 */
	@Override
	public void enablePlayControl(boolean modo) {
		enableButton(playButton, modo);
	}

	/**
	 * Trata a habilitacao do botao de pausa de tempo
	 */
	@Override
	public void enablePauseControl(boolean modo) {
		enableButton(pauseButton, modo);
		
	}

	/**
	 * Trata a habilitacao do botao de restart de tempo
	 */
	@Override
	public void enableRestartControl(boolean modo) {
		enableButton(restartButton, modo);
	}

	/**
	 * Atualiza o modo de contraste na tela
	 */
	@Override
	public void updateContrastMode(ContrastMode contrastMode){
    	contrastModeTextView.setText(contrastMode.getText());
    	contrastModeTextView.setTextColor(contrastMode.getTextColor());
    	
		timeTextView.setTextColor(contrastMode.getTextColor());
		
		repetitionTextView.setTextColor(contrastMode.getTextColor());
	}
	
	/**
	 * Atualiza o texto de repeticao da tela
	 */
	@Override
	public void updateRepetitionText(int repetition, int repetitions){
		Resources res = getResources();
		StringBuilder sb = new StringBuilder(res.getString(R.string.repetition_text_1)).append(" ");
		sb.append(repetition).append(" ");
		sb.append(res.getString(R.string.repetition_text_2)).append(" ");
		sb.append(repetitions);
		repetitionTextView.setText(sb.toString());
	}

	/**
	 * Inicia o contador
	 */
	@Override
	public void startCountDownTimer() {
		counter = new AppCountDownTimer(this, minutes, seconds);
    	counter.start();
	}

	/**
	 * Para o contador
	 */
	@Override
	public void stopCountDownTimer() {
		if(counter != null){
			counter.cancel();
			counter = null;
		}
	} 
	
	/**
	 * Controla a criacao das telas de dialogo
	 */
	@Override
    protected Dialog onCreateDialog(int id) {
    	Dialog d = null;
    	
    	//Dialogo About
    	if ( id == Constants.DIALOG_ABOUT ) {
    		d = DialogAbout.create(this,getApplicationContext(), LAYOUT_INFLATER_SERVICE);
    		
    	//Dialogo Saida da Aplicacao pelo Botao Voltar
    	} else if ( id == DIALOG_CONFIRM_EXIT_APP ) {
    		AlertDialog.Builder builder = new AlertDialog.Builder(this);
    		builder.setMessage(R.string.exit_app_message)
    		       .setCancelable(false)
    		       .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
    		           public void onClick(DialogInterface dialog, int id) {
    		        	   cancelCounter();
    		        	   	
    		        	   Intent resultIntent = new Intent(); 
    		        	   resultIntent.putExtra(Constants.SAIR_DA_APLICACAO, "1"); 
    		        	   setResult(Activity.RESULT_OK, resultIntent);  
    		        	   finish();
    		           }
    		       })
    		       .setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
    		           public void onClick(DialogInterface dialog, int id) {
    		                dialog.cancel();
    		           }
    		       });
    		d = builder.create();
    		
    	// Dialogo de fim de sessao
    	} else if ( id == DIALOG_SESSION_FINISH ) {
    		AlertDialog.Builder builder = new AlertDialog.Builder(this);
    		builder.setMessage(R.string.dialog_finish_app_message);
    		builder.setTitle(R.string.dialog_finish_app_title);
    		builder.setIcon(android.R.drawable.ic_dialog_info);
    		builder.setNeutralButton("OK", new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int which) {
					if ( listener.playSound() )
    					alarmRingtone.stop();
	        	   
    				if ( listener.vibrate())
    					((Vibrator)getSystemService(VIBRATOR_SERVICE)).cancel();
    				
					finish();
				}
			});
    		d = builder.create();
    	}
    	
    	return d;
    }
	
	private void cancelCounter(){
		if(counter != null){
		   	counter.cancel();
			counter = null;
		}
	}
	
	/**
	 * Monta o menu da atividade
	 */
	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(0, MENU_RESTART_SESSION, 0, R.string.menu_restart_session).setIcon(android.R.drawable.ic_menu_revert);
    	menu.add(0, MENU_CONFIG, 1, R.string.menu_configuration).setIcon(android.R.drawable.ic_menu_preferences);
    	menu.add(0, MENU_ABOUT, 1, R.string.about_title).setIcon(android.R.drawable.ic_menu_info_details);
    	return true;
    }
    
	/**
	 * Controla o item do menu selecionado
	 */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    	if ( item.getItemId() == MENU_RESTART_SESSION ) {
    		listener.restartSession();
    	}else if ( item.getItemId() == MENU_ABOUT ) {
    		showDialog(Constants.DIALOG_ABOUT);
    	} else if ( item.getItemId() == MENU_CONFIG ) {
    		finish();
    	}
    	return true;
    }
    
    /**
     * Verifica se o botão do android de voltar foi pressionado
     */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
    	if ( keyCode == KeyEvent.KEYCODE_BACK) {
    		showDialog(DIALOG_CONFIRM_EXIT_APP);
    		return true;
    	} else {
    		return super.onKeyDown(keyCode, event);
    	}
    }
    
  //used in onCreate() and onConfigurationChanged() to set up the UI elements 
    public void InitializeUI(boolean resetTime){ 
		bindViewComponents();
		configureViews();
		
        Bundle extras = getIntent().getExtras();  
        if(extras != null) {
        	if(this.listener == null){
        		ContrastSession contrastSession = (ContrastSession) extras.getSerializable(Constants.CONTRAST_SESSION);
            	setPresenter(new ContrastSessionPresenter(this,contrastSession));
            	listener.startSession();
        	}
             listener.startScreen(resetTime);
        }
        
       
    	
    } 
    
    @Override
    public void restoreMode(){
    	if(this.actualMode == Mode.init){
     		setInitMode();
     	}else if(this.actualMode == Mode.pause){
     		setPauseMode();
     	}else if(this.actualMode == Mode.running){
     		setRunningMode();
     	}
    }
     
    //this is called when the screen rotates. 
    // (onCreate is no longer called when screen rotates due to manifest, see: android:configChanges) 
    @Override 
    public void onConfigurationChanged(Configuration newConfig){ 
        super.onConfigurationChanged(newConfig); 
        setContentView(R.layout.contrast); 
     
        updateTextView(minutes,seconds);
        InitializeUI(false); 
    } 
    

    private void notificacao(String text) {
       NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
       Notification notification = new Notification(R.drawable.icon, "Easy Contrast", System.currentTimeMillis());
		
		Intent notificationIntent = new Intent(this, ContrastActivity.class);
		PendingIntent content = PendingIntent.getActivity(this, 0, notificationIntent, 0);
		
		StringBuffer note = new StringBuffer(getResources().getString(Integer.valueOf(listener.getContrastModeAtualText())));
		note.append(": ").append(text).append(" (");
		note.append(getResources().getString(R.string.repetition_text_1));
		note.append(listener.getRepetitionCount()).append(")");
		notification.setLatestEventInfo(this, "Easy Contrast", note.toString(), content);
		
		notificationManager.notify(0, notification);
	}
    
    private void cancelNotificacao(){
    	NotificationManager mgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
    	mgr.cancel(0);
    }
    
    @Override
    protected void onDestroy() {
    	super.onDestroy();
    	cancelCounter();
    	cancelNotificacao();
    }
}
